package org.ruoyi.system.util;

import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

/**
 * 微信接口工具类，用于获取微信 OpenID
 */
public class WeChatApiUtil {
    private static final Logger log = LoggerFactory.getLogger(WeChatApiUtil.class);
    // 替换为你的微信小程序 appId
    private static final String APP_ID = "wxc519946404b838f8";
    // 替换为你的微信小程序 appSecret
    private static final String APP_SECRET = "b4395f23b7dc5c55a5fc11fdc576afca";
    private static final String OPENID_URL = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";

    /**
     * 根据微信授权码获取 OpenID
     *
     * @param code 微信授权码
     * @return OpenID，获取失败返回 null
     */
    public static String getOpenIdByCode(String code) {
        if (code == null || code.isEmpty()) {
            log.error("获取 OpenID 失败，code 为空");
            return null;
        }
        try {
            String urlStr = String.format(OPENID_URL, APP_ID, APP_SECRET, code);
            URL url = new URL(urlStr);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();

            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                reader.close();

                JSONObject jsonObject = JSONObject.parseObject(response.toString());
                if (jsonObject.containsKey("openid")) {
                    return jsonObject.getString("openid");
                } else {
                    log.error("获取 OpenID 失败，微信接口返回错误: {}", jsonObject.toJSONString());
                }
            } else {
                log.error("获取 OpenID 失败，HTTP 响应码: {}", responseCode);
            }
        } catch (Exception e) {
            log.error("获取 OpenID 失败，发生异常", e);
        }
        return null;
    }

    /**
     * 根据微信授权码获取 OpenID 和 session_key
     *
     * @param code 微信授权码
     * @return 包含 openid 和 session_key 的 JSONObject，获取失败返回 null
     */
    public static JSONObject getOpenIdAndSessionKey(String code) {
        if (code == null || code.isEmpty()) {
            log.error("获取 OpenID 和 session_key 失败，code 为空");
            return null;
        }
        try {
            String urlStr = String.format(OPENID_URL, APP_ID, APP_SECRET, code);
            URL url = new URL(urlStr);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();

            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                reader.close();

                JSONObject jsonObject = JSONObject.parseObject(response.toString());
                if (jsonObject.containsKey("openid") && jsonObject.containsKey("session_key")) {
                    return jsonObject;
                } else {
                    log.error("获取 OpenID 和 session_key 失败，微信接口返回错误: {}", jsonObject.toJSONString());
                }
            } else {
                log.error("获取 OpenID 和 session_key 失败，HTTP 响应码: {}", responseCode);
            }
        } catch (Exception e) {
            log.error("获取 OpenID 和 session_key 失败，发生异常", e);
        }
        return null;
    }

    /**
     * 根据加密数据和偏移向量解密微信小程序用户手机号码
     *
     * @param encryptedData 加密的手机号码数据
     * @param iv            加密算法的初始向量
     * @param sessionKey    微信会话密钥
     * @return 解密后的手机号码信息，失败返回 null
     */
    public static String getPhoneNumber(String encryptedData, String iv, String sessionKey) {
        try {
            // 解密
            byte[] encryptedDataBytes = Base64.getDecoder().decode(encryptedData);
            byte[] sessionKeyBytes = Base64.getDecoder().decode(sessionKey);
            byte[] ivBytes = Base64.getDecoder().decode(iv);

            SecretKeySpec secretKeySpec = new SecretKeySpec(sessionKeyBytes, "AES");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);

            byte[] decryptedBytes = cipher.doFinal(encryptedDataBytes);
            String decryptedData = new String(decryptedBytes, StandardCharsets.UTF_8);

            JSONObject jsonObject = JSONObject.parseObject(decryptedData);
            if (jsonObject.containsKey("phoneNumber")) {
                return jsonObject.getString("phoneNumber");
            }
        } catch (Exception e) {
            log.error("解密手机号码失败，发生异常", e);
        }
        return null;
    }
}
